#pragma once
#include "Vector2.h"

class BasePlayer;
class Ball;
class GameState;

/*
	SteeringBehaviors.
	This class calculate movements to sadisfy an agent's goal.
	You can turn Off and On different kind of movements. Default is Off. I.E. : SeekOn() and SeekOff().
	Every Update you should Calculate the new force, then apply it on agent's speed to get the new position.
*/

class SteeringBehaviors
{

public:
	SteeringBehaviors(BasePlayer* bp);
	~SteeringBehaviors();

	Vector2 GetTarget()const{ return m_target; }
	void SetTarget(const Vector2 target){ m_target = target; }

	Vector2 GetInterposeFrom()const{ return m_interposeFrom; }
	void SetInterposeFrom(const Vector2 from){ m_interposeFrom = from; }
	Vector2 GetInterposeTo()const{ return m_interposeTo; }
	void SetInterposeTo(const Vector2 to){ m_interposeTo = to; }
	float GetInterposeWeight()const{ return m_interposeWeight; }
	void SetInterposeWeight(const float weight){ m_interposeWeight = weight; }
	
	Vector2 GetForce()const{ return m_steering; }

	void Calculate();

	inline void SeekOn(){ m_iFlags |= seek; }
	inline void ArriveOn(){ m_iFlags |= arrive; }
	inline void DodgeOn(){ m_iFlags |= dodge; }
	inline void PursuitOn(){ m_iFlags |= pursuit; }
	inline void InterposeOn(){ m_iFlags |= interpose; }

	inline void SeekOff(){ if(SeekIsOn()) m_iFlags ^= seek; }
	inline void ArriveOff(){ if(ArriveIsOn()) m_iFlags ^= arrive; }
	inline void DodgeOff(){ if(DodgeIsOn()) m_iFlags ^= dodge; }
	inline void PursuitOff(){ if(PursuitIsOn()) m_iFlags ^= pursuit; }
	inline void InterposeOff(){ if(InterposeIsOn()) m_iFlags ^= interpose; }

	inline bool SeekIsOn(){ return On(seek); }
	inline bool ArriveIsOn(){ return On(arrive); }
	inline bool DodgeIsOn(){ return On(dodge); }
	inline bool PursuitIsOn(){ return On(pursuit); }
	inline bool InterposeIsOn(){ return On(interpose); }

private:
	
	BasePlayer*		m_player;
	Ball*			m_ball;

	Vector2			m_steering;
	Vector2			m_target;

	Vector2			m_interposeFrom;
	Vector2			m_interposeTo;
	float			m_interposeWeight;

	int           m_iFlags;

	enum Behaviors
	{
		none               = 0x0000,
		seek               = 0x0001,
		arrive             = 0x0002,
		dodge			   = 0x0004,
		pursuit            = 0x0008,
		interpose          = 0x0010
	};

	bool	On(Behaviors bt){return ((m_iFlags & bt) == bt);}

	void SumForces();

	Vector2 Seek(Vector2& target);
	Vector2 Arrive(Vector2& target);
	Vector2 Interpose(Vector2& from, Vector2& to, float weight);
	Vector2 Pursuit();
	Vector2 Dodge();

};
